<?php

/**
 * Manager/TemplateManager.php
 */

namespace RHX\Model\Manager;

use Zend\Db\Adapter\Adapter;
use RHX\Model\Object\XCalculator;
use RHX\Helper\RHDateTime;
use RHX\Model\Object\EmployeTemplate;
use RHX\Model\Object\PlanningTemplate;
use RHX\Model\Object\Employe;
use Zend\Debug\Debug;
use RH2\Model\Object\XRules;

class TemplateManager {

    const INACTIF		 = 0;
    const ACTIF		 = 1;
    const AJOUTER		 = 2;
    const EFFACER		 = 3;
    const EGAL		 = 0;
    const INFERIEUR	 = -1;
    const SUPERIEUR	 = 1;

    protected $adapter;

    public function __construct(Adapter $adapter) {
	$this->adapter = $adapter;
    }

    /**
     * Adapteur de base de données
     *
     * @return Adapter
     */
    public function getAdapter() {
	return $this->adapter;
    }

    /**
     * Charge un planning type vide ou à partir des disponibilités pour la liste des employés présent sur le site
     *
     * @param int $site Identifiant du site
     * @param boolean $disponibilite Indicateur si on rempli avec les disponibilités
     * @return array
     */
    public function loadNewEmpty($site, $disponibilite = false) {
	// Nom des jours de la semaines
	$dayNames	 = array(
	    'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche',
	);
	// Calculateur
	$calculator	 = new XCalculator($this->getAdapter());
	// table Employé
	$tableEmploye	 = new \RHX\Model\Table\EmployeTable($this->getAdapter());
	$employeList	 = $tableEmploye->getEmployesBySiteEx2($site, 'poste_rang asc, prenom asc');
	$templates	 = array();
	// parcours de la liste des employés
	foreach ($employeList as $e) {
	    $template		 = new \RHX\Model\Object\EmployeTemplate($this->getAdapter());
	    $template->matricule	 = $e->matricule;
	    $heurePrevue		 = new \RHX\Helper\RHDateTime();
	    $heurePrevue->setTime();
	    if ($disponibilite) {
		$dispo = $e->getDisponibilite();
		foreach ($dayNames as $day) {
		    $dayCode		 = $day . '_code';
		    $dayEntree		 = $day . '_entree';
		    $daySortie		 = $day . '_sortie';
		    $dayPause		 = $day . '_pause';
		    $dayRepas		 = $day . '_repas';
		    $template->$dayCode	 = (int) $dispo->$day;
		    $template->$dayEntree	 = $dispo->$dayEntree;
		    $template->$daySortie	 = $dispo->$daySortie;
		    $template->$dayPause	 = ($calculator->isPause($template->$dayEntree, $template->$daySortie, '05:00')) ? 1 : 0;
		    $template->$dayRepas	 = ($calculator->isRepas($template->$dayEntree, $template->$daySortie, '12:00', '14:00')) ? 1 : 0;
		    $dataDay		 = $calculator->oneDayCalcul($e->matricule, $template->$dayCode, $template->$dayEntree, $template->$daySortie, $template->$dayPause, $template->$dayRepas, $day);
		    $heurePrevue->addHours($dataDay->tempsDiff, false);
		}
	    }
	    $template->heure_prevues = $heurePrevue->totalHours();
	    $templates[]		 = $template;
	}
	// table code activité
	$tableCode	 = new \RHX\Model\Table\CodeActiviteTable($this->getAdapter());
	$codeList	 = $tableCode->getAll();
	$couleurs	 = array();
	// parcours de la liste des codes activités
	foreach ($codeList as $c) {
	    $couleurs[$c->code] = $c->couleur;
	}

	return array(
	    'templates'	 => $templates,
	    'couleurs'	 => $couleurs,
	);
    }

    /**
     * Charge les copies des plannings types en fonction des employés sur les sites
     * Si l'employé n'a pas de planning type alors on lui crée un planning type de disponibilite
     * @param int $site
     * @param int $templateId
     * @return type
     */
    public function loadNewCopy($site, $templateId) {
	// Jours de la semaines
	$dayNames		 = array(
	    'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche',
	);
	// Calculateur
	$calculator		 = new XCalculator($this->getAdapter());
	// table employés
	$tableEmploye		 = new \RHX\Model\Table\EmployeTable($this->getAdapter());
	$employeList		 = $tableEmploye->getEmployesBySiteEx2($site, 'poste_rang asc, prenom asc');
	// table planning type
	$tableTemplate		 = new \RHX\Model\Table\PlanningTemplateTable($this->getAdapter());
	$template		 = $tableTemplate->getTemplate($templateId);
	$employeTemplateList	 = $template->getTemplates();
	$employeTemplates	 = array();
	// parcours de la liste des templates employés
	foreach ($employeTemplateList as $emplTpl) {
	    $employeTemplates[(int) $emplTpl->matricule] = $emplTpl;
	}
	$templates = array();
	// parcours de la liste des employés
	foreach ($employeList as $e) {
	    $template = (isset($employeTemplates[(int) $e->matricule])) ? $employeTemplates[(int) $e->matricule] : null;
	    if (is_null($template)) {
		// L'employé n'a pas de template qui lui est déjà créé
		// Donc on crée un template pour l'employé on lui assignant ses disponibilités
		$template	 = new \RHX\Model\Object\EmployeTemplate($this->getAdapter());
		$dispo		 = $e->getDisponibilite();
		foreach ($dayNames as $day) {
		    $dayCode		 = $day . '_code';
		    $dayEntree		 = $day . '_entree';
		    $daySortie		 = $day . '_sortie';
		    $dayPause		 = $day . '_pause';
		    $dayRepas		 = $day . '_repas';
		    $template->$dayCode	 = (int) $dispo->$day;
		    $template->$dayEntree	 = $dispo->$dayEntree;
		    $template->$daySortie	 = $dispo->$daySortie;
		    $template->$dayPause	 = ($calculator->isPause($template->$dayEntree, $template->$daySortie, '05:00')) ? 1 : 0;
		    $template->$dayRepas	 = ($calculator->isRepas($template->$dayEntree, $template->$daySortie, '12:00', '14:00')) ? 1 : 0;
		}
	    }
	    $templates[] = $template;
	}
	$tableCode	 = new \RHX\Model\Table\CodeActiviteTable($this->getAdapter());
	$codeList	 = $tableCode->getAll();
	$couleurs	 = array();
	foreach ($codeList as $c) {
	    $couleurs[$c->code] = $c->couleur;
	}
	return array(
	    'templates'	 => $templates,
	    'couleurs'	 => $couleurs
	);
    }

    /**
     * Sauvegarde d'un nouveau planning type
     *
     * @param \Zend\Stdlib\Parameters $post
     * @return array
     */
    public function saveNew($post) {
	// jour de la semaine
	$dayName			 = array(
	    'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche',
	);
	$tableEmployeTemplate		 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());
	$tablePlanningTemplate		 = new \RHX\Model\Table\PlanningTemplateTable($this->getAdapter());
	// enregistrement du planning type
	$planningTemplate		 = new \RHX\Model\Object\PlanningTemplate($this->getAdapter());
	$planningTemplate->libelle	 = $post->libelle;
	$planningTemplate->site_id	 = $post->site;
	$planningTemplate->creation	 = $planningTemplate->edition	 = date('Y-m-d');
	$planningTemplate->template	 = 0;
	$planningTemplate->id		 = $planningTemplate->template	 = $tablePlanningTemplate->save($planningTemplate);
	$planningTemplate->actif	 = 1;
	$planningTemplate->parent	 = 0;
	$tablePlanningTemplate->save($planningTemplate);
	$templates			 = array();
	// liste des employés
	foreach ($post->employes as $matricule) {
	    $template		 = new \RHX\Model\Object\EmployeTemplate($this->getAdapter());
	    $template->matricule	 = $matricule;
	    $template->template	 = $planningTemplate->template;
	    foreach ($dayName as $day) {
		$dayCode		 = $day . '_code';
		$dayEntree		 = $day . '_entree';
		$daySortie		 = $day . '_sortie';
		$dayPause		 = $day . '_pause';
		$dayRepas		 = $day . '_repas';
		$matriculeCode		 = "$matricule-$day-code";
		$matriculeEntree	 = "$matricule-$day-entree";
		$matriculeSortie	 = "$matricule-$day-sortie";
		$matriculePause		 = "$matricule-$day-pause";
		$matriculeRepas		 = "$matricule-$day-repas";
		// assignation des valeurs
		$template->$dayCode	 = is_null($post->$matriculeCode)   ? XRules::NeTravaillePas :  $post->$matriculeCode;
		$template->$dayEntree	 = is_null($post->$matriculeEntree) ? 0: $post->$matriculeEntree ;
		$template->$daySortie	 = is_null($post->$matriculeSortie) ? 0: $post->$matriculeSortie;
		$template->$dayPause	 = is_null($post->$matriculePause)  ? 0 : $post->$matriculeSortie;
		$template->$dayRepas	 = is_null($post->$matriculeRepas)  ? 0: $post->$matriculeRepas;
	    }
	    $template->heure_prevues = $post->heure_prevues;
	    // sauvegarde des détails du planning type (c-a-d par employé)
	    $template->id		 = $tableEmployeTemplate->save($template);
	    $templates[]		 = $templates;
	}
	return array(
	    'templates'		 => $templates,
	    'planningTemplate'	 => $planningTemplate,
	);
    }

    /**
     * Récupérer toutes les couleurs des codes activités
     * 
     * @return array
     */
    public function getColors() {
	$tableCode	 = new \RHX\Model\Table\CodeActiviteTable($this->getAdapter());
	$codeList	 = $tableCode->getAll();
	$colors		 = array();
	foreach ($codeList as $c) {
	    $colors[$c->code] = $c->couleur;
	}

	return $colors;
    }

    /**
     * Récupérer le Codec des codes activités
     * 
     * @return array
     */
    public function getCodec() {
	$tableCode	 = new \RHX\Model\Table\CodeActiviteTable($this->getAdapter());
	$codeList	 = $tableCode->getAll();
	$codec		 = array();
	foreach ($codeList as $c) {
	    $codec[(int) $c->id] = $c->code;
	}

	return $codec;
    }

    /**
     * Tous les codes activités
     * 
     * @return type
     */
    public function getCodes() {
	$tableCode	 = new \RHX\Model\Table\CodeActiviteTable($this->getAdapter());
	$codeList	 = $tableCode->getAll('id ASC', true);
	$codes		 = array();
	foreach ($codeList as $c) {
	    $codes[] = $c;
	}

	return $codes;
    }

    /**
     * Récupérer le site en cours
     * 
     * @param int $site
     * @return \RHX\Model\Object\Site
     */
    public function getSite($site) {
	$tableSite	 = new \RHX\Model\Table\SiteTable($this->getAdapter());
	$site		 = $tableSite->get($site);

	return $site;
    }

    /**
     * Récupération des données pour le popover
     * 
     * @param \Zend\Stdlib\Parameters $post
     * @return array
     */
    public function getPopoverData($post) {
	$matricule	 = (int) $post->matricule;
	$prefix		 = $post->prefix;
	$id		 = (int) $post->id;
	$code		 = 0;
	$entree		 = '00:00';
	$sortie		 = '00:00';
	$repas		 = 0;
	$pause		 = 0;
	if ($id != 0) {
	    $tableEmployeTemplate	 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());
	    $employeTemplate	 = $tableEmployeTemplate->get($id);
	    $dayCode		 = $prefix . '_code';
	    $dayEntree		 = $prefix . '_entree';
	    $daySortie		 = $prefix . '_sortie';
	    $dayPause		 = $prefix . '_pause';
	    $dayRepas		 = $prefix . '_repas';
	    $code			 = (int) $employeTemplate->$dayCode;
	    $entree			 = RHDateTime::hourNoSecond($employeTemplate->$dayEntree);
	    $sortie			 = RHDateTime::hourNoSecond($employeTemplate->$daySortie);
	    $pause			 = (int) $employeTemplate->$dayPause;
	    $repas			 = (int) $employeTemplate->$dayRepas;
	}
	else {
	    $code	 = (int) $post->code;
	    $entree	 = $post->entree;
	    $sortie	 = $post->sortie;
	    $pause	 = (int) $post->pause;
	    $repas	 = (int) $post->repas;
	}

	return array(
	    'employe'	 => $employe	 = $this->getEmploye($matricule),
	    'code'		 => $this->getCode($code),
	    'entree'	 => $entree,
	    'sortie'	 => $sortie,
	    'repas'		 => $repas,
	    'pause'		 => $pause,
	    'prefix'	 => $prefix,
	    'id'		 => $id,
	);
    }

    /**
     * Récupérer un employé
     * 
     * @param int $matricule
     * @return \RHX\Model\Object\Employe
     */
    public function getEmploye($matricule) {
	$tableEmploye = new \RHX\Model\Table\EmployeTable($this->getAdapter());
	try {
	    return $tableEmploye->get($matricule);
	}
	catch (\Exception $ex) {
	    return null;
	}
    }

    /**
     * Récupérer le code d'activité
     * 
     * @param int $code
     * @return \RHX\Model\Object\CodeActivite
     */
    public function getCode($code) {
	$tableCode = new \RHX\Model\Table\CodeActiviteTable($this->getAdapter());
	try {
	    return $tableCode->get($code);
	}
	catch (\Exception $ex) {
	    return null;
	}
    }

    /**
     * Dupliquer un planning type
     * 
     * @param int $template
     * @return array
     */
    public function duplicate__($template) {
	// planning template
	$tablePlanningTemplate		 = new \RHX\Model\Table\PlanningTemplateTable($this->getAdapter());
	$planningTemplate		 = $tablePlanningTemplate->get($template);
	// duplication
	$planningTemplate->id		 = 0;
	$planningTemplate->actif	 = 0;
	$planningTemplate->parent	 = $template;
	$newId				 = $tablePlanningTemplate->save($planningTemplate);
	$planningTemplate->id		 = $newId;
	$planningTemplate->template	 = $newId;
	$tablePlanningTemplate->save($planningTemplate);
	// employe template
	$tableEmployeTemplate		 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());
	$templates			 = $tableEmployeTemplate->getTemplates($template);
	// parcours de la liste des templates et création du nouvel enregistrement
	$newTemplates			 = array();
	foreach ($templates as $template) {
	    $template->id		 = 0;
	    $template->template	 = $newId;
	    $template->id		 = $tableEmployeTemplate->save($template);
	    $newTemplates[]		 = $template;
	}

	return array(
	    'old'	 => $tablePlanningTemplate->get($template),
	    'new'	 => $planningTemplate,
	    'copy'	 => $newTemplates,
	);
    }

    /**
     * Indique si un template est utilisé ou pas dans la génération d'un planning semaine
     * 
     * @param int $template
     * @return boolean
     */
    public function isUsed($template) {
	$viewPS	 = new \RHX\Model\View\PSPlanningView($this->getAdapter());
	$ps	 = $viewPS->getTemplates($template);
	if ($ps->count() > 0) {
	    return true;
	}
	return false;
    }

    /**
     * Ajouter un employé
     * 
     * @param \RHX\Model\Object\Employe $employe
     */
    public function addEmploye(Employe $employe) {
	$tablePlanningTemplate	 = new \RHX\Model\Table\PlanningTemplateTable($this->getAdapter());
	$planningTemplates	 = $tablePlanningTemplate->getAllBySite($employe->site_id);

	foreach ($planningTemplates as $template) {
	    if ($this->isUsed($template->template)) {
		$this->duplicate($template);
	    }
	    $this->appendTemplate($employe, $template->template);
	}
    }

    /**
     * Effacer un employe
     * 
     * @param \RHX\Model\Object\Employe $employe
     */
    public function removeEmploye(Employe $employe) {
	$tablePlanningTemplate	 = new \RHX\Model\Table\PlanningTemplateTable($this->getAdapter());
	$planningTemplates	 = $tablePlanningTemplate->getAllBySite($employe->site_id);

	foreach ($planningTemplates as $template) {
	    if ($this->isUsed($template->template)) {
		$this->duplicate($template);
	    }
	    $this->appendTemplate($employe, $template->template);
	}
    }

    /**
     * Ajouter un employé à un planning type données
     * 
     * @param \RHX\Model\Object\Employe $employe
     * @param int $tpl
     * @return \RHX\Model\Object\EmployeTemplate
     */
    public function appendTemplate_(Employe $employe, $tpl) {
	$tableEmployeTemplate	 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());
	$template		 = new EmployeTemplate($this->getAdapter());
	$dayName		 = array(
	    'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche',
	);
	$dispo			 = $employe->getDisponibilite();
	$calculator		 = new XCalculator($this->getAdapter());
	foreach ($dayName as $day) {
	    $dayCode		 = $day . '_code';
	    $dayEntree		 = $day . '_entree';
	    $daySortie		 = $day . '_sortie';
	    $dayPause		 = $day . '_pause';
	    $dayRepas		 = $day . '_repas';
	    $template->$dayCode	 = $dispo->$day;
	    $template->$dayEntree	 = $dispo->$dayEntree;
	    $template->$daySortie	 = $dispo->$daySortie;
	    $template->$dayPause	 = $calculator->isPause($template->$dayEntree, $template->$daySortie) ? 1 : 0;
	    $template->$dayRepas	 = $calculator->isRepas($template->$dayEntree, $template->$daySortie) ? 1 : 0;
	}
	$template->template	 = $tpl;
	$template->matricule	 = $employe->matricule;
	$template->id		 = $tableEmployeTemplate->save($template);

	return $template;
    }

    /**
     * 
     * @param \RHX\Model\Object\Employe $employe
     * @param type $tpl
     * @return array
     */
    public function appendRemoveTemplate(Employe $employe, $tpl) {
	$tableEmployeTemplate	 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());
	$template		 = $tableEmployeTemplate->getEmployeTemplate($employe->matricule, $tpl);
	if ($template) {
	    // Effacer l'enregistrement de la base de données
	}
	return array(
	    'done'		 => false,
	    'template'	 => $template,
	);
    }

    /**
     * Dupliquer un Template
     * 
     * @param int $templateId
     * @return array
     */
    public function duplicateTemplate($templateId) {
	//Debug::dump('', "Dupliquer un template");
	$tablePlanningTemplate		 = new \RHX\Model\Table\PlanningTemplateTable($this->getAdapter());
	$planningTemplate		 = $tablePlanningTemplate->getTemplate($templateId);
	// dupliquer le résumé
	$planningTemplate->id		 = 0;
	$planningTemplate->template	 = 0;
	$planningTemplate->parent	 = $templateId;
	$planningTemplate->creation	 = date('Y-m-d');
	$planningTemplate->edition	 = date('Y-m-d');
	$planningTemplate->id		 = $planningTemplate->template	 = $tablePlanningTemplate->save($planningTemplate);
	$tablePlanningTemplate->save($planningTemplate);
	$oldPT				 = $tablePlanningTemplate->getTemplate($templateId);
	$this->duplicateTemplateContent($templateId, $planningTemplate->template);
	$this->changeStateTemplate($templateId, self::INACTIF);
	//Debug::dump($oldPT, 'Template dupliqué');
	//Debug::dump($planningTemplate, 'Template nouveau');

	return array(
	    'old'	 => $oldPT,
	    'new'	 => $planningTemplate,
	);
    }

    /**
     * Dupliquer le contenu d'un planning type
     * 
     * @param int $oldId
     * @param int $newId
     * @return array
     */
    public function duplicateTemplateContent($oldId, $newId) {
	//Debug::dump('', "Dupliquer le contenu d'un template");
	$tableEmployeTemplate	 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());
	$templates		 = $tableEmployeTemplate->getTemplates($oldId);
	$newTemplates		 = array();
	$done			 = false;
	foreach ($templates as $template) {
	    $template->id		 = 0;
	    $template->template	 = $newId;
	    $template->id		 = $tableEmployeTemplate->save($template);
	    $newTemplates[]		 = $template;
	    $done			 = true;
	}
	//Debug::dump($done, ($done) ? "Succès" : "Erreur");
	//Debug::dump($newTemplates, "Nouveau Template");
	return array(
	    'done'	 => $done,
	    'new'	 => $newTemplates,
	);
    }

    /**
     * Modifier un planning type
     * 
     * @param \RHX\Model\Object\Employe $employe
     * @param int $templateId
     * @param int $type
     * @return array
     */
    public function appendTemplate(Employe $employe, $templateId, $type) {
	$done		 = false;
	$template	 = null;
	switch ($type) {
	    case self::AJOUTER:
		return $this->addToTemplate($employe, $templateId);
	    case self::EFFACER:
		return $this->removeFromTemplate($employe, $templateId);
	}
	//Debug::dump($done, ($done) ? "Template modifié avec Succès" : "Template non-modifié Erreur");
	//Debug::dump($template, "Template modifié");
	return array(
	    'done'		 => $done,
	    'template'	 => $template,
	);
    }

    /**
     * Ajouter un employé d'un planning type
     * 
     * @param \RHX\Model\Object\Employe $employe
     * @param int $templateId
     * @return array
     */
    public function addToTemplate(Employe $employe, $templateId) {
	//Debug::dump('', "Ajouter Employé {$employe->matricule} au template #$templateId");
	$done			 = false;
	// chargement du template
	$tableEmployeTemplate	 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());
	$template		 = new EmployeTemplate($this->getAdapter());
	$dispo			 = $employe->getDisponibilite();
	$dayName		 = array('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche');
	$calculator		 = new XCalculator($this->getAdapter());
	foreach ($dayName as $day) {
	    $dayCode		 = $day . '_code';
	    $dayEntree		 = $day . '_entree';
	    $daySortie		 = $day . '_sortie';
	    $dayPause		 = $day . '_pause';
	    $dayRepas		 = $day . '_repas';
	    $template->$dayCode	 = $dispo->$day;
	    $template->$dayEntree	 = $dispo->$dayEntree;
	    $template->$daySortie	 = $dispo->$daySortie;
	    $template->$dayPause	 = ($calculator->isPause($template->$dayEntree, $template->$daySortie)) ? 1 : 0;
	    $template->$dayRepas	 = ($calculator->isRepas($template->$dayEntree, $template->$daySortie)) ? 1 : 0;
	}
	$template->template	 = $templateId;
	$template->matricule	 = $employe->matricule;
	$template->id		 = $tableEmployeTemplate->save($template);
	if ($template->id != 0) {
	    $done = true;
	}
	//Debug::dump($done, ($done) ? "Ajouter avec succès" : "Erreur d'ajout'");
	//Debug::dump($template, "Template ajouter");

	return array(
	    'done'		 => $done,
	    'template'	 => $template,
	);
    }

    /**
     * Effacer un employé d'un planning Type
     * 
     * @param \RHX\Model\Object\Employe $employe
     * @param int $templateId
     * @return array
     */
    public function removeFromTemplate(Employe $employe, $templateId) {
	//Debug::dump('', "Effacer Employé {$employe->matricule} du template #$templateId");
	$done			 = false;
	$template		 = null;
	$tableEmployeTemplate	 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());
	$template		 = $tableEmployeTemplate->getEmployeTemplate($employe->matricule, $templateId);
	//effacer
	$nb			 = 0;
	$nb			 = $tableEmployeTemplate->eraseTemplate($employe->matricule, $templateId);
	//Debug::dump($nb, 'Nombre de template effacé');
	if ($nb > 0) {
	    $done = true;
	}
	//Debug::dump($done, ($done) ? "Effacer avec succès" : "Erreur de suppression'");
	//Debug::dump($template, "Template Effacer");

	return array(
	    'done'		 => $done,
	    'template'	 => $template,
	);
    }

    /**
     * Changer l'état d'un Planning Type
     * 
     * @param int $templateId
     * @param int $state
     * @return array
     */
    public function changeStateTemplate($templateId, $state) {
	//Debug::dump('', "Changer l'état du template #$templateId en $state");
	$done			 = false;
	$template		 = null;
	$tablePlanningTemplate	 = new \RHX\Model\Table\PlanningTemplateTable($this->getAdapter());
	$planningTemplate	 = $tablePlanningTemplate->getTemplate($templateId);
	if ($state == self::ACTIF || $state == self::INACTIF) {
	    $planningTemplate->actif = $state;
	}
	else {
	    $planningTemplate->actif = self::ACTIF;
	}
	$id	 = 0;
	$id	 = $tablePlanningTemplate->save($planningTemplate);
	if ($id != 0) {
	    $done = true;
	}
	//Debug::dump($done, ($done) ? "Changement d'état réussie" : "Changement d'état Erreur");
	//Debug::dump($planningTemplate, "Template édité");

	return array(
	    'done'		 => $done,
	    'template'	 => $template,
	);
    }

    /**
     * Mise à jour de tous les plannings types
     * Après traitement tous les plannings types auront un double,
     * et c'est le double qui prendra sa place dans la liste
     * des plannings types
     */
    public function updateAllTemplate($site = 0) {
	//Debug::dump('', '0-Mise à jour de tous les plannings types');
	$employes	 = $this->getEmployes($site);
	$lastWeek	 = null;
	$lastSite	 = 0;
	$templates	 = $this->getTemplatesBySite($site);
	foreach ($employes as $employe) {
	    $simplyAdd = false;
	    if ($lastSite != (int) $employe->site_id) {
		$lastSite	 = (int) $site;
		//Debug::dump($lastSite, 'Nouveau site');
		$lastWeek	 = $this->getLastGenerateWeek($lastSite);
		if (is_null($lastWeek)) {
		    // Il n'y a pas de semaine généré,
		    // donc on fait un simple ajout dans les planning type
		    //Debug::dump('', "1-Il n'y a pas de semaine généré donc on ajoute simplement l'employé (#$employe->matricule)");
		    echo '<pre>' . (($this->simpleAdd($employe)) ? "Ajout réussi (#$employe->matricule)" : "Il n'y aucun template auquelle ajouter l'employé (#$employe->matricule)") . '</pre>';
		    $simplyAdd = true;
		}
	    }
	    $sortie = ($employe->contrat_fin != '0000-00-00') ? $employe->contrat_fin : null;
	    // Comparaison
	    if (is_null($sortie)) {
		// Supérieur ou null
		if (is_null($lastWeek) && (!$simplyAdd)) {
		    //Debug::dump('', "2-Il n'y a pas de semaine généré donc on ajoute simplement l'employé (#$employe->matricule)");
		    echo '<pre>' . (($this->simpleAdd($employe)) ? "Ajout réussi (#$employe->matricule)" : "Il n'y aucun template auquelle ajouter l'employé (#$employe->matricule)") . '</pre>';
		    echo '<hr>';
		    continue;
		}
		$sortie = new RHDateTime();
		$sortie->modify('next year');
		//Debug::dump($sortie, "3-La date de sortie est NULL et changer à la date {$sortie->date()} (#$employe->matricule)");
		$this->afterWeek($lastWeek, $sortie, $employe);
	    }
	    else {
		$sortie = new RHDateTime($sortie);
		//Debug::dump($sortie, "4-La date de sortie n'est pas NULL '{$sortie->date()}'");
		if (is_null($lastWeek)) {
		    //Debug::dump('', "5-Il n'y a pas de semaine généré donc on ajoute simplement l'employé (#$employe->matricule)");
		    if ($this->simpleAdd($employe)) {
			echo '<pre>' . (($simply) ? "Ajout réussi (#$employe->matricule)" : "Il n'y aucun template auquelle ajouter l'employé (#$employe->matricule)") . '</pre>';
			echo '<hr>';
			continue;
		    }
		}
		if (is_null($lastWeek)) {
		    //Debug::dump('', "6-Il n'y a pas de semaine généré donc on prend la semaine en cours comme référence'");
		    $table	 = new \RHX\Model\Table\SemaineTable($this->getAdapter());
		    $semaine = $table->getSemaineByDate();
		    $this->switches($semaine, $sortie, $employe);
		}
		else {
		    //Debug::dump('', "6-Test de la date de sortie ({$sortie->date()})");
		    $this->switches($lastWeek, $sortie, $employe);
		}
	    }
	    echo '<hr>';
	}
    }

    /**
     * Redirection des éléments
     * @param \RHX\Model\Object\Semaine $semaine
     * @param \RHX\Helper\RHDateTime $sortie
     * @param \RHX\Model\Object\Employe $employe
     */
    private function switches(\RHX\Model\Object\Semaine $semaine, RHDateTime $sortie, Employe $employe) {
	$result = $this->compareToWeek($semaine, $sortie);
	//Debug::dump($result, "7-Résultat de Comparaison $result");
	switch ($result) {
	    case self::EGAL:
		// la date de fin de contrat fait partie de la semaine
		$this->inWeek($semaine, $sortie, $employe);
		break;
	    case self::SUPERIEUR:
		// la date de fin de contrat est encore supérieur à la semaine
		$this->afterWeek($semaine, $sortie, $employe);
		break;
	    case self::INFERIEUR:
		// la date de fin de contrat est déjà passé par rapport à la semaine
		$this->beforeWeek($semaine, $sortie, $employe);
		break;
	}
    }

    /**
     * la date de fin de contrat fait partie de la semaine
     * l'employé est considéré comme présent sur le site
     * donc il sera encore ajouté au plannings type
     * 
     * @param \RHX\Model\Object\Semaine $semaine
     * @param \RHX\Helper\RHDateTime $sortie
     * @param \RHX\Model\Object\Employe $employe
     */
    private function inWeek(\RHX\Model\Object\Semaine $semaine, RHDateTime $sortie, Employe $employe) {
	//Debug::dump('', "13-La date de fin appartient à la dernière semaine générée");
	$this->afterWeek($semaine, $sortie, $employe);
    }

    /**
     * la date de fin de contrat est encore supérieur à la semaine
     * l'employé en question sera ajouter aux plannings types
     * 
     * @param \RHX\Model\Object\Semaine $semaine
     * @param \RHX\Helper\RHDateTime $sortie
     * @param \RHX\Model\Object\Employe $employe
     */
    private function afterWeek(\RHX\Model\Object\Semaine $semaine, RHDateTime $sortie, Employe $employe) {
	// plannings types non-obsolètes
	//Debug::dump('', "12-La date de fin de contrat ({$sortie->date()}) est supérieur à la date de la dernière semaine généré '{$semaine->dimanche}' (#$employe->matricule)");
	// $templates = $employe->getTemplates();
	$templates = $this->getTemplatesBySite($employe->site_id);
	foreach ($templates as $template) {
	    //Debug::dump('', '13-Analyse du template');
	    if (!$this->isInTemplate($employe, $template->template)) {
		if ($this->isUsed($template->template)) {
		    //Debug::dump('', "14-Le Template n°{$template->template} est déjà utilisé");
		    $this->duplicateTemplate($template->template);
		}
		$this->appendTemplate($employe, $template->template, self::AJOUTER);
	    }
	}
    }

    /**
     * la date de fin de contrat est déjà passé par rapport à la semaine
     * l'employé en question sera effacé au plannings types
     * 
     * @param \RHX\Model\Object\Semaine $semaine
     * @param \RHX\Helper\RHDateTime $sortie
     * @param \RHX\Model\Object\Employe $employe
     */
    private function beforeWeek(\RHX\Model\Object\Semaine $semaine, RHDateTime $sortie, Employe $employe) {
	// plannings types non-obsolètes
	//Debug::dump('', "8-La date de fin de contrat ({$sortie->date()}) est inférieure à la date de la dernière semaine généré (#$employe->matricule)");
	// $templates = $employe->getTemplates();
	$templates = $this->getTemplatesBySite($employe->site_id);
	foreach ($templates as $template) {
	    //Debug::dump('', '9-Analyse du template');
	    if (!$this->isInTemplate($employe, $template->template)) {
		if ($this->isUsed($template->template)) {
		    //Debug::dump('', "Le Template n°{$template->template} est déjà utilisé");
		    $data = $this->duplicateTemplate($template->template);
		    $this->duplicateTemplateContent($data['old']->template, $data['new']->template);
		}
		//Debug::dump('', "11-Effacer l'employé du planning Template Template");
		$this->appendTemplate($employe, $template->template, self::EFFACER);
	    }
	    else {
		// Il est dans le template
		// A effacer
		//Debug::dump('', "10-Effacer l'employé du planning Template Template");
		$this->appendTemplate($employe, $template->template, self::EFFACER);
	    }
	}
    }

    /**
     * Tous les employés
     * 
     * @param boolean $actif
     * @return \Zend\Db\ResultSet\ResultSet
     */
    public function getEmployes($site, $actif = true) {
	$tableEmploye = new \RHX\Model\Table\EmployeTable($this->getAdapter());
	return $tableEmploye->getEmployesBySite($site, 'matricule ASC', 1, 100, $actif);
    }

    /**
     * Tous les Plannings type du site
     * 
     * @param int $siteId
     * @return ResultSet
     */
    public function getTemplatesBySite($siteId) {
	$tablePlanningTemplate = new \RHX\Model\Table\PlanningTemplateTable($this->getAdapter());
	return $tablePlanningTemplate->getAllBySite($siteId);
    }

    /**
     * Récupérer la dernière semaine généré pour le site
     * 
     * @param type $siteId
     * @return \RHX\Model\Object\Semaine
     */
    public function getLastGenerateWeek($siteId) {
	$viewPS = new \RHX\Model\View\PSPlanningView($this->getAdapter());
	return $viewPS->getLastWeek($siteId);
    }

    /**
     * Compare la date au jour de la semaine
     * -1 si la date est avant la semaine
     * +1 si la date est après la semaine
     *  0 si la date est entre le lundi et le dimanche de la semaine
     *
     * @param \RHX\Model\Object\Semaine $semaine
     * @param string $date
     * @return int
     */
    public function compareToWeek(\RHX\Model\Object\Semaine $semaine, $date) {
	$lundi		 = new RHDateTime($semaine->lundi);
	$dimanche	 = new RHDateTime($semaine->dimanche);
	$date		 = new RHDateTime($date);
	if ($date->isLT($lundi)) {
	    return self::INFERIEUR;
	}
	elseif ($date->isGT($dimanche)) {
	    return self::SUPERIEUR;
	}
	else {
	    return self::EGAL;
	}
    }

    /**
     * Détermine si une date fait partie de la semaine donnée
     * 
     * @param \RHX\Model\Object\Semaine $semaine
     * @param string $date
     * @return boolean
     */
    public function isWeekBetween(\RHX\Model\Object\Semaine $semaine, $date) {
	$lundi		 = new RHDateTime($semaine->lundi);
	$dimanche	 = new RHDateTime($semaine->dimanche);
	$date		 = new RHDateTime($date);
	return $date->isBetween($lundi, $dimanche);
    }

    /**
     * Comparaison à une date
     * 
     * @param string $date
     * @param string $ref
     * @return int
     */
    public function compareToDate($date, $ref) {
	$date	 = new RHDateTime($date);
	$ref	 = new RHDateTime($ref);
	if ($date->isEqual($ref)) {
	    return self::EGAL;
	}
	if ($date->isGT($ref)) {
	    return self::SUPERIEUR;
	}
	else {
	    return self::INFERIEUR;
	}
    }

    /**
     * Ajouter un employé à tous ses templates
     * 
     * @param \RHX\Model\Object\Employe $employe
     * @return boolean
     */
    private function simpleAdd(Employe $employe) {
	$tablePlanningTemplate	 = new \RHX\Model\Table\PlanningTemplateTable($this->getAdapter());
	$templates		 = $tablePlanningTemplate->getAllBySite($employe->site_id);
	//Debug::dump($templates, "Templates de l'employé #$employe->matricule");
	if ($templates->count() > 0) {
	    // parcours
	    foreach ($templates as $template) {
		if (!$this->isInTemplate($employe, $template->id)) {
		    //Debug::dump('', "Puisque l'employé ($employe->matricule) n'est pas encore dans le template, on l'ajoute'''");
		    $this->appendTemplate($employe, $template->id, self::AJOUTER);
		    return true;
		}
		else {
		    //Debug::dump('', "L'employé est déjà dans le template'");
		}
	    }
	}
	return false;
    }

    /**
     * Détermine si un employé est dans le template
     * 
     * @param \RHX\Model\Object\Employe $employe
     * @param int $templateId
     * @return boolean
     */
    public function isInTemplate(Employe $employe, $templateId) {
	$tableEmployeTemplate	 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());
	$template		 = $tableEmployeTemplate->getEmployeTemplate($employe->matricule, $templateId);
	//Debug::dump($template, "Résultat des templates pour l'employé $employe->matricule et le template $templateId");
	echo '<pre>' . (($template) ? "L'employé ($employe->matricule) éxiste déjà dans le template" : "L'employé ($employe->matricule) n'existe pas dans le template") . '</pre>';

	return ($template) ? true : false;
    }

}
